package cn.hesion.inputformat;
/**
 * ClassName: CustomRecordReader <br/>
 * Description: <br/>
 * date: 2021/2/3 17:09<br/>
 *
 * @author Hesion<br />
 * @version
 * @since JDK 1.8
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.ByteWritable;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.io.IOException;

/**
 * @program: ClientDemo
 * @description:
 * @author: hesion
 * @create: 2021-02-03 17:09
 **/
public class CustomRecordReader extends RecordReader<Text, BytesWritable> {

    private Configuration conf;
    private FileSplit split;

    //是否读取到内容的标识符
    private boolean isProgress = true;

    //输出的kv
    private BytesWritable value = new BytesWritable();
    private Text k = new Text();

    @Override
    public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
        this.split = (FileSplit) split;
        conf = context.getConfiguration();
    }

    @Override
    public boolean nextKeyValue() throws IOException, InterruptedException {
        if (isProgress) {
            //定义一个缓冲区
            byte[] contents = new byte[(int) split.getLength()];

            FileSystem fs = null;
            FSDataInputStream fis = null;
            try {

                // 获取文件系统
                Path path = split.getPath();
                fs = path.getFileSystem(conf);


                //3读取数据
                fis = fs.open(path);

                //4读取文件内容
                IOUtils.readFully(fis, contents, 0, contents.length);

                //5 输出文件内容
                value.set(contents, 0, contents.length);

                //6获取文件路径及名称
                String name = split.getPath().toString();
                k.set(name);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeStream(fis);
            }
            isProgress = false;
            return true;

        }
        return false;
    }

    @Override
    public Text getCurrentKey() throws IOException, InterruptedException {
        return k;
    }

    @Override
    public BytesWritable getCurrentValue() throws IOException, InterruptedException {
        return value;
    }

    @Override
    public float getProgress() throws IOException, InterruptedException {
        return 0;
    }

    @Override
    public void close() throws IOException {

    }
}
